package com.kuang.saleTicket;

import java.util.concurrent.locks.ReentrantLock;

/**
 *  基本的卖票例子   使用JUC（java.util.concurrent.locks  三个接口： 1.Condition 2.Lock 3.ReadWriteLock，使用Lock）
 *
 * @author sdm
 * @version 1.0
 * @date 2023/6/19 17:27
 */
public class SaleTicketDemo02JUC {

    /*
        公平锁、非公平锁区别：
            公平锁：先来后到
            非公平锁：可以插队（默认非公平锁）
        public ReentrantLock() {
            sync = new ReentrantLock.NonfairSync();  // 默认非公平锁
        }
        public ReentrantLock(boolean fair) {
            sync = fair ? new ReentrantLock.FairSync() : new ReentrantLock.NonfairSync();
        }


        sychnorized 和 lock锁使用区别：
            sychnorized：自动挡，不需要手动创建锁、释放锁
            lock锁：手动挡，需要手动创建锁，释放锁，走lock三部曲就行
                1. new ReentrantLock(),   new可重入锁
                2. Lock.lock(）加锁，
                3. finally {Lock.unlock()}  解锁
     */


    public static void main(String[] args) {

        // 并发：多线程操作同一资源类，将资源类丢入线程
        Ticket1 ticket1 = new Ticket1();

        new Thread(()->{for (int i = 0; i < 15; i++) ticket1.sale();}, "线程A").start();  // A线程卖15张票
        new Thread(()->{for (int i = 0; i < 15; i++) ticket1.sale();}, "线程B").start();  // B线程卖15张票
        new Thread(()->{for (int i = 0; i < 15; i++) ticket1.sale();}, "线程C").start();  // C线程卖15张票
        /*
            线程A卖出了第30票，剩余：29
            线程A卖出了第29票，剩余：28
            线程C卖出了第28票，剩余：27
            线程C卖出了第27票，剩余：26
            线程C卖出了第26票，剩余：25
            线程C卖出了第25票，剩余：24
            线程C卖出了第24票，剩余：23
            线程C卖出了第23票，剩余：22
            线程C卖出了第22票，剩余：21
            线程C卖出了第21票，剩余：20
            线程C卖出了第20票，剩余：19
            线程C卖出了第19票，剩余：18
            线程C卖出了第18票，剩余：17
            线程C卖出了第17票，剩余：16
            线程C卖出了第16票，剩余：15
            线程C卖出了第15票，剩余：14
            线程C卖出了第14票，剩余：13
            线程B卖出了第13票，剩余：12
            线程B卖出了第12票，剩余：11
            线程B卖出了第11票，剩余：10
            线程B卖出了第10票，剩余：9
            线程B卖出了第9票，剩余：8
            线程B卖出了第8票，剩余：7
            线程B卖出了第7票，剩余：6
            线程B卖出了第6票，剩余：5
            线程B卖出了第5票，剩余：4
            线程B卖出了第4票，剩余：3
            线程B卖出了第3票，剩余：2
            线程B卖出了第2票，剩余：1
            线程B卖出了第1票，剩余：0
         */
    }
}

class Ticket1 {

    // new一个可重入锁
    private final ReentrantLock lock = new ReentrantLock();

    private int number = 30;

    public void sale(){
        lock.lock(); //加锁
        try {
            // 业务代码
            if (number > 0){
                System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "票，剩余：" + number);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock(); // 释放锁
        }

    }
}
